# -*- coding: utf-8 -*-

'''
Created on 04.12.2009

@author: stud
'''

import sys, traceback, Ice
import Demo
import vtk
import math
import time
from Tkinter import *
from vtk.tk.vtkTkRenderWidget import *

global bodyList 
global numberOfBodies
global sphereList


status = 0
ic = None
numberOfBodies=100
loopRunning = False
exitRequested = False
currentTime=0.0
timeStep=0.1



def setRadi():
        global sphereList
        sphereList = []
       
        for i in range(numberOfBodies):
            sphere = vtk.vtkSphereSource()
            sphere.SetRadius(bodyList[i].radius*1000)
            sphere.SetPhiResolution(20)
            sphere.SetThetaResolution(20)
            sphereMapper = vtk.vtkPolyDataMapper()
            sphereMapper.SetInputConnection(sphere.GetOutputPort())
            sphereActor = vtk.vtkActor()
            sphereActor.SetMapper(sphereMapper)
            ren.AddActor(sphereActor)
            sphereList.append(sphereActor)
def quit():
        global exitRequested, loopRunning, root, vis
        if loopRunning:
            exitRequested = True    
        else:
            root.quit()
            
def renderOneStep():
        
        global  root, bodyList, sphereList, loopRunning, exitRequested
        bodyList = printer.getBodyStructList()
        setRadi()
        
        
        loopRunning = True
        while not exitRequested:
            global vis, timeStep,  sphereList
            time.sleep(timeStep)               
            if printer.calcOneStep() == 1: 
                #TODO: return wert für calcOneStep() einfuegen
                bodyList = printer.getBodyStructList()
               
            for i in range(0,len(bodyList)-1):
                
                positionx = bodyList[i].posX
                positiony = bodyList[i].posY
                positionz = bodyList[i].posZ
                sphereList[i].SetPosition(positionx, positiony, positionz)
                print str(positionx) +', ' +str(positiony) +', ' +str(positionz)
                   
#                ren.ResetCamera()       
                renderWindow.Render()
                root.update() 
                
        root.quit()
     


           

try:
    ic = Ice.initialize(sys.argv)
    base = ic.stringToProxy("SimplePrinter:default -p 10000")
    printer = Demo.PrinterPrx.checkedCast(base)
    if not printer:
        raise RuntimeError("Invalid proxy")
    #dem Server die benoetigten Parameter uebergeben um ein MultiBodySystem
    #erstellen zu koennen.
    printer.setNumberOfBodies(100)
    printer.setLowerLimitMass(22)
    printer.setUpperLimitMass(27)
    printer.setLowerLimitRadii(6)
    printer.setUpperLimitRadii(7)
    printer.setMassCentralBody(1.99E30)
    printer.setSpaceCircumferenceLowerLimit(9)
    printer.setSpaceCircumferenceUpperLimit(12)
    printer.setDeltaT(86400)
    #ein RandomMultiBodySystem auf dem Server instanziieren
    printer.initRandomMultiBodySystem()
    root = Tk()
    root.title('Mehrkoerpersystem') 
    root.protocol("WM_DELETE_WINDOW", quit)
    
    
                
    entryFrame = Frame(root)
    
    ipEntry = Entry(entryFrame)   
    ipEntry.pack(side = TOP)
    portEntry = Entry(entryFrame)
    portEntry.pack(side = TOP)
    massminEntry = Entry(entryFrame)
    massminEntry.pack(side = TOP)
    massmaxEntry = Entry(entryFrame)
    massmaxEntry.pack(side = TOP)
    radiminEntry = Entry(entryFrame)
    radiminEntry.pack(side = TOP)
    radimaxEntry = Entry(entryFrame)
    radimaxEntry.pack(side = TOP) 
    xEntry = Entry(entryFrame)    
    xEntry.pack(side = TOP)
    yEntry = Entry(entryFrame)
    yEntry.pack(side = TOP)
    zEntry = Entry(entryFrame)
    zEntry.pack(side = TOP)
    centralStarMassEntry = Entry(entryFrame)
    centralStarMassEntry.pack(side = TOP)
    
    entryFrame.pack(side = RIGHT)

    labelFrame = Frame(root)
    
    ipLabel = Label(labelFrame, text="IP:")
    ipLabel.pack(side=TOP, ipady = 1)
    portLabel = Label(labelFrame, text="Port:")
    portLabel.pack(side= TOP, ipady = 1)
    minmassLabel = Label(labelFrame, text = "Min_Mass:")
    minmassLabel.pack(side= TOP, ipady = 1)
    maxmassLabel = Label(labelFrame, text = "Max_Mass:")
    maxmassLabel.pack(side= TOP, ipady = 1)
    radiminLabel = Label(labelFrame, text = "Min_Radius:")
    radiminLabel.pack(side= TOP, ipady = 1)
    radimaxLabel = Label(labelFrame, text = "Max_Radius:")
    radimaxLabel.pack(side= TOP, ipady = 1)
    xLabel = Label(labelFrame, text = "Ausdehnung_x:")
    xLabel.pack(side= TOP, ipady = 1)
    yLabel = Label(labelFrame, text = "Ausdehnung_y:")
    yLabel.pack(side= TOP, ipady = 1)
    zLabel = Label(labelFrame, text = "Ausdehnung_z:")
    zLabel.pack(side= TOP, ipady = 1)
    CentralStarLabel = Label(labelFrame, text = "Masse_Zentralgestirn:")
    CentralStarLabel.pack(side= TOP, ipady = 1)
    
    labelFrame.pack(side = RIGHT, expand = False)
   
    
    ren = vtk.vtkRenderer()
    
   
        
       
    ren.SetBackground(0.1, 0.2, 0.4)
    light = vtk.vtkLight()
    light.SetPosition(- 200, - 200, 200)    # hier muss Zentralgesirn hin
    ren.AddLight(light)
    cam = ren.GetActiveCamera()
    cam.SetPosition(0, -600, 0)
    cam.SetFocalPoint(0, 0, 0)
    cam.SetViewUp(0, 0, 1)
    cam.SetViewAngle(40)
    cam.SetClippingRange(0, 1000)
    ren.SetActiveCamera(cam)
    ren.ResetCamera()
    

    renderWidget = vtkTkRenderWidget(root, width = 500, height = 500)
    ren.SetBackground(0.1, 0.2, 0.4)
    renderWindow = renderWidget.GetRenderWindow()
    renderWindow.AddRenderer(ren)   
    renderWindow.SetSize(300, 300)
    #
   
  
    
    renderWidget.pack(expand = 'true', fill = 'both')      
    #
    startButton = Button(root, text = 'Start', command = renderOneStep)
    startButton.pack(expand = 'true', fill = 'x')
    quitButton = Button(root, text = "Quit", command = quit)
    quitButton.pack(expand = 'true', fill = 'x')
    
    #
#    
#    renderOneStep()
   
        
       
    root.mainloop()  
    
 
    
    
    
except:
    traceback.print_exc()
    status = 1
    
if ic:
   #Clean up
   try:
       ic.destroy()
   except:
        traceback.print_exc()
        status = 1
    
sys.exit(status)
